﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KohvikRax.Resources.Src
{
    public class DataSync
    {
        private delegate void UpdateGlobalData(EDataTypeUpdate edtu, int id = -1);

        private static DataSync _dataSync;
        private static CoffeeService.ServiceClient _service;
        private static CoffeeService.EntityKohvik[] _kohvikEntityList;  // TODO cache
        private static CoffeeService.EntityUudis[] _uudisEntityList;
        private static List<Comment> _selectedCafeComments;
        private static List<OpenTime> _selectedCafeOpenTimes;
        private static int _selectedCafeCommentCount = 0;
        private static int _selectedCafeId = -1;
        private static readonly List<object> queueKeepers =
            new List<object>(6);
        
        private EDataTypeUpdate _globalUpdateSettings;

        private DataSync() { }
        static DataSync()
        {
            _selectedCafeComments = new List<Comment>(10);
            _selectedCafeOpenTimes = new List<OpenTime>(7);
            _service = new CoffeeService.ServiceClient();

            for (int i = 0; i < 6; i++)
            {
                queueKeepers.Add(new object());
            }
        }

        public static DataSync GetInstance()
        {
            return (_dataSync == null) ? _dataSync = new DataSync() : _dataSync;
        }

        public void UpdateData(EDataTypeUpdate edtu, int id = -1) // TODO Proper thread controll
        {
            int j = -1;

                if (edtu.Has(EDataTypeUpdate.TopNews))
                {
                    lock (queueKeepers[++j])
                        _uudisEntityList = _service.getEntityUudisListByAmount(10);
                }

                if (edtu.Has(EDataTypeUpdate.AllKohvikEntities))
                {
                    lock (queueKeepers[++j])
                    _kohvikEntityList = _service.getEntityKohvikList();
                }

                if (edtu.Has(EDataTypeUpdate.CafeOpenTimes))
                {
                    lock (queueKeepers[++j])
                    GetCafeOpenTimes(id);
                }

                if (edtu.Has(EDataTypeUpdate.CafeCommentCount))
                {
                    lock (queueKeepers[++j])
                    GetSelectedCafeCommentCount(id);
                }

                if (edtu.Has(EDataTypeUpdate.CafeComments))
                {
                    lock (queueKeepers[++j])
                    GetSelectedCafeComments(id);
                }
        }

        public void StartAsyncUpdater(int intervalInSeconds, AsyncCallback callback)
        {
            var dispatcherTimer = new System.Windows.Threading.DispatcherTimer();

            dispatcherTimer.Tick += delegate(object sender, EventArgs e)
            {
                UpdateGlobalData u = UpdateData;
                u.BeginInvoke(_globalUpdateSettings, -1, callback, null); // Bug
                
            };

            dispatcherTimer.Interval = new TimeSpan(0, 0, intervalInSeconds);
            
            dispatcherTimer.Start();
        }

        private void GetSelectedCafeComments(int id)
        {
            if (id == -1) throw new ArgumentException("Please include the required id param @ Datasync UpdateData(). Called from GetSelectedCafeComments");
            _selectedCafeId = id;
            var comments = _service.getEntityKommentaarFor(CoffeeService.KommentaarType.Kohvik, id);
            if(_selectedCafeComments.Count != 0) _selectedCafeComments.Clear();
            var sb = new StringBuilder(100);
            foreach (var comment in comments)
            {
                sb.Append(comment.Autor);
                sb.Append(" | ");
                sb.Append(comment.Aeg.Day);
                sb.Append("-");
                sb.Append(comment.Aeg.Month);
                sb.Append("-");
                sb.Append(comment.Aeg.Year);
                sb.Append(" | ");
                sb.Append(comment.Aeg.TimeOfDay);
                _selectedCafeComments.Add(new Comment()
                    {
                        Header = sb.ToString(),
                        Body = comment.Tekst
                    });
                sb.Clear();
            }
        }

        private void GetSelectedCafeCommentCount(int id)
        {
            if (id == -1) throw new ArgumentException("Please include the required id param @ Datasync UpdateData(). Called from GetSelectedCafeCommentCount");
            _selectedCafeId = id;
            _selectedCafeCommentCount = _service.getCommentCountFor(CoffeeService.KommentaarType.Kohvik, id);
        }

        private void GetCafeOpenTimes(int id)
        {
            if (id == -1) throw new ArgumentException("Please include the required id param @ Datasync UpdateData(). Called from GetOpenTimes");
            _selectedCafeId = id;
            var lahtiolekuajad = _service.getEntityLahtiolekuAjadByKohvikId(id);

            if (_selectedCafeOpenTimes.Count != 0) 
            {
                _selectedCafeOpenTimes.Clear();
            }

            if ( (lahtiolekuajad == null || lahtiolekuajad.Count() == 0) )
            {
                return;
            }

            var sb = new StringBuilder(100);
            foreach (var lahtiolekuaeg in lahtiolekuajad)
            {

                var openTime = new OpenTime()
                {
                    Day = lahtiolekuaeg.Lyhend
                };
                sb.Clear();
                sb.Append(" : ");
                sb.Append(lahtiolekuaeg.Avamisaeg.ToString().Remove(5));
                sb.Append(" - ");
                sb.Append(lahtiolekuaeg.Sulgemisaeg.ToString().Remove(5));
                openTime.Period = sb.ToString();

                sb.Clear();
                _selectedCafeOpenTimes.Add(openTime);
            }

        }

        public List<Comment> SelectedCafeComments
        {
            get { return DataSync._selectedCafeComments; }
            set { DataSync._selectedCafeComments = value; }
        }

        public int SelectedCafeId
        {
            get { return _selectedCafeId; }
        }
        public int SelectedCafeCommentCount
        {
            get { return _selectedCafeCommentCount; }
        }

        public IEnumerable<OpenTime> SelectedCafeOpenTimes
        {
            get { return DataSync._selectedCafeOpenTimes as IEnumerable<OpenTime>; }
        }
        public EDataTypeUpdate UpdateSettings
        {
            get { return _globalUpdateSettings; }
            set { _globalUpdateSettings = value; }
        }
        public IEnumerable<CoffeeService.EntityKohvik> KohvikEntityList
        {
            get { return DataSync._kohvikEntityList as IEnumerable<CoffeeService.EntityKohvik>; }
        }
        public IEnumerable<CoffeeService.EntityUudis> UudisEntityList
        {
            get { return DataSync._uudisEntityList as IEnumerable<CoffeeService.EntityUudis>; }
        }
    }
}
